from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.db.models import Q
from system.models import Department
from system.SysUtils.permission import permission_required, data_permission_required
from .dept_serializers import DeptSerializer, DeptCreateSerializer, DeptUpdateSerializer, DeptFormSerializer
import jwt
from django.conf import settings
from django.shortcuts import get_object_or_404


class DeptView(APIView):
    """部门管理视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    @permission_required(["sys:dept:query"])
    def get(self, request, *args, **kwargs):
        """
        获取部门列表（树形结构）
        
        查询参数:
        - keywords: 关键字(部门名称)
        - status: 状态(1->正常；0->禁用)
        """
        # 获取查询参数
        keywords = request.query_params.get('keywords', '')
        status = request.query_params.get('status')
        
        # 构建查询条件
        query = Q(parent_id=0)
        
        # 如果提供了关键字，则添加关键字过滤
        if keywords:
            # 使用递归CTE查询，找出所有包含关键字的部门及其所有父部门
            # 由于Django不直接支持递归CTE查询，这里采用先找出所有匹配关键字的部门，
            # 然后递归向上找父部门的方式来实现
            matching_depts = Department.objects.filter(name__icontains=keywords)
            
            if matching_depts.exists():
                # 找出匹配关键字的部门的所有父部门ID
                parent_ids = set()
                for dept in matching_depts:
                    # 如果有tree_path字段，直接解析
                    if dept.tree_path:
                        parent_ids.update(int(pid) for pid in dept.tree_path.split(',') if pid)
                    
                    # 将当前部门ID加入集合
                    parent_ids.add(dept.id)
                
                # 不应用parent_id=0筛选，而是查询所有符合条件的部门
                query = Q(id__in=parent_ids) | Q(parent_id__in=parent_ids)
        
        # 获取状态筛选条件
        dept_status = None
        if status is not None:
            try:
                dept_status = int(status)
                # 注意：不在顶层过滤，而是在序列化时处理，以保持树形结构
            except ValueError:
                pass
        
        # 按排序字段和ID排序
        depts = Department.objects.filter(query, is_deleted=0).order_by('sort', 'id')
        
        # 序列化
        context = {'status': dept_status}
        serializer = DeptSerializer(depts, many=True, context=context)
        
        # 返回数据
        return Response({
            "code": "00000",
            "data": serializer.data,
            "msg": "获取部门列表成功"
        })
    
    @permission_required(["sys:dept:add"])
    def post(self, request, *args, **kwargs):
        """
        创建部门
        
        请求体:
        {
          "name": "研发部",
          "code": "RD001",
          "parentId": 1000,
          "status": 1,
          "sort": 1
        }
        """
        # 从token中获取用户ID
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token = token.split(" ")[1]
            try:
                # 解码token获取用户ID
                decoded_token = jwt.decode(token, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                user_id = None
        else:
            user_id = None
        
        # 创建序列化器，传入用户ID
        serializer = DeptCreateSerializer(data=request.data, context={'user_id': user_id})
        
        if serializer.is_valid():
            # 保存部门
            dept = serializer.save()
            
            # 返回成功响应
            return Response({
                "code": "00000",
                "data": DeptSerializer(dept).data,
                "msg": "部门创建成功"
            })
        else:
            # 返回验证错误
            return Response({
                "code": "A0400",
                "data": {},
                "msg": serializer.errors
            }, status=400)

    @permission_required(["sys:dept:edit"])
    def put(self, request, *args, **kwargs):
        """
        更新部门
        
        路径参数:
        - id: 部门ID
        
        请求体:
        {
          "id": 1001,
          "name": "研发部",
          "code": "RD001",
          "parentId": 1000,
          "status": 1,
          "sort": 1
        }
        """
        # 获取部门ID
        dept_id = kwargs.get('id')
        if not dept_id:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "请指定要更新的部门ID"
            }, status=400)
        
        # 获取部门对象
        try:
            dept = Department.objects.get(id=dept_id, is_deleted=0)
        except Department.DoesNotExist:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "部门不存在或已被删除"
            }, status=404)
        
        # 检查数据权限
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token = token[7:]  # 去掉"Bearer "前缀
            data_permission = data_permission_required(token, "update", dept.create_by)
            if data_permission is False:
                return Response({
                    "code": "A0401",
                    "data": {},
                    "msg": "无权限修改此部门"
                }, status=403)
        
        # 从token中获取用户ID
        try:
            decoded_token = jwt.decode(token, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
            user_id = decoded_token.get('user_id')
        except jwt.InvalidTokenError:
            user_id = None
        
        # 使用更新序列化器
        serializer = DeptUpdateSerializer(dept, data=request.data, context={'user_id': user_id})
        
        if serializer.is_valid():
            # 更新部门
            updated_dept = serializer.save()
            
            # 返回成功响应
            return Response({
                "code": "00000",
                "data": DeptSerializer(updated_dept).data,
                "msg": "部门更新成功"
            })
        else:
            # 返回验证错误
            return Response({
                "code": "A0400",
                "data": {},
                "msg": serializer.errors
            }, status=400)
    
    @permission_required(["sys:dept:delete"])
    def delete(self, request, *args, **kwargs):
        """
        删除部门
        
        路径参数:
        - id: 部门ID，多个以英文逗号(,)分割
        """
        # 获取部门ID
        dept_id = kwargs.get('id')
        if not dept_id:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "请指定要删除的部门ID"
            }, status=400)
        
        # 处理多个ID情况
        dept_ids = str(dept_id).split(',')
        try:
            dept_ids = [int(did) for did in dept_ids if did]
        except ValueError:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "部门ID格式不正确"
            }, status=400)
        
        if not dept_ids:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "请指定要删除的部门ID"
            }, status=400)
        
        # 查询要删除的部门
        depts_to_delete = Department.objects.filter(id__in=dept_ids, is_deleted=0)
        
        # 检查是否存在子部门
        child_depts = Department.objects.filter(parent_id__in=dept_ids, is_deleted=0)
        if child_depts.exists():
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "存在子部门，无法删除"
            }, status=400)
        
        # 检查数据权限
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token = token[7:]  # 去掉"Bearer "前缀
            
            # 检查每个部门的权限
            unauthorized_depts = []
            for dept in depts_to_delete:
                data_permission = data_permission_required(token, "delete", dept.create_by)
                if data_permission is False:
                    unauthorized_depts.append(dept.name)
            
            if unauthorized_depts:
                return Response({
                    "code": "A0401",
                    "data": {},
                    "msg": f"无权限删除部门：{', '.join(unauthorized_depts)}"
                }, status=403)
        
        # 逻辑删除部门
        count = depts_to_delete.count()
        depts_to_delete.update(is_deleted=1)
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": {},
            "msg": f"成功删除{count}个部门"
        })


class DeptOptionsView(APIView):
    """部门下拉选项视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:dept:query"])
    def get(self, request, *args, **kwargs):
        """
        获取部门下拉选项列表
        
        返回树形结构的部门选项，用于前端下拉框选择
        """
        # 检查数据权限
        token = request.headers.get("Authorization")
        data_permission = data_permission_required(token, "select")
        
        # 构建查询条件
        query = Q(parent_id=0, is_deleted=0, status=1)
        
        # 添加数据权限过滤
        if isinstance(data_permission, list) and data_permission:
            # 如果返回的是用户ID列表，只查询这些用户创建的部门
            query &= Q(create_by__in=data_permission)
        
        # 获取顶级部门
        root_depts = Department.objects.filter(query).order_by('sort', 'id')
        
        # 递归构建树形结构
        result = []
        for dept in root_depts:
            dept_option = {
                "value": str(dept.id),
                "label": dept.name,
            }
            
            # 递归获取子部门
            children = self._get_children_options(dept.id, data_permission)
            if children:
                dept_option["children"] = children
            
            result.append(dept_option)
        
        # 返回数据
        return Response({
            "code": "00000",
            "data": result,
            "msg": "一切ok"
        })
    
    def _get_children_options(self, parent_id, data_permission=None):
        """递归获取子部门选项"""
        # 构建查询条件
        query = Q(parent_id=parent_id, is_deleted=0, status=1)
        
        # 添加数据权限过滤
        if isinstance(data_permission, list) and data_permission:
            query &= Q(create_by__in=data_permission)
        
        # 查询子部门
        child_depts = Department.objects.filter(query).order_by('sort', 'id')
        
        result = []
        for dept in child_depts:
            dept_option = {
                "value": str(dept.id),
                "label": dept.name,
            }
            
            # 递归获取子部门
            children = self._get_children_options(dept.id, data_permission)
            if children:
                dept_option["children"] = children
            
            result.append(dept_option)
        
        return result


class DeptFormView(APIView):
    """部门表单数据视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:dept:query"])
    def get(self, request, *args, **kwargs):
        """
        获取部门表单数据
        
        路径参数:
        - id: 部门ID
        
        返回部门的表单数据，用于前端编辑
        """
        # 获取部门ID
        dept_id = kwargs.get('id')
        if not dept_id:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "请指定部门ID"
            }, status=400)
        
        # 获取部门对象
        try:
            dept = Department.objects.get(id=dept_id, is_deleted=0)
        except Department.DoesNotExist:
            return Response({
                "code": "A0400",
                "data": {},
                "msg": "部门不存在或已被删除"
            }, status=404)
        
        # 检查数据权限
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token = token[7:]  # 去掉"Bearer "前缀
            data_permission = data_permission_required(token, "select", dept.create_by)
            if data_permission is False:
                return Response({
                    "code": "A0401",
                    "data": {},
                    "msg": "无权限查看此部门"
                }, status=403)
        
        # 序列化部门数据
        serializer = DeptFormSerializer(dept)
        
        # 返回数据
        return Response({
            "code": "00000",
            "data": serializer.data,
            "msg": "一切ok"
        })
